home *** CD-ROM | disk | FTP | other *** search
/ Gamers Delight 2 / Gamers Delight 2.iso / Aminet / game / misc / Orm.lha / Orm / Orm.c < prev    next >
C/C++ Source or Header  |  1993-12-22  |  10KB  |  494 lines

  1. /*
  2.  * This is a modified version of Michael Warner's
  3.  * Public Domain Workbench SNAKE game.
  4.  *
  5.  * This (improved?) version by Torsten Poulin
  6.  * is, of course, still in the public domain.
  7.  *
  8.  *   Torsten Poulin
  9.  *   Banebrinken 99, 2, 77
  10.  *   DK-2400 Copenhagen NV
  11.  *   DENMARK
  12.  *
  13.  * THIS IS A WB 2+ PROGRAM!!!
  14.  *
  15.  * $Log:    Orm.c,v $
  16.  * Revision 1.4  93/10/21  16:21:23  Torsten
  17.  * Pause key changed from 'P' to spacebar.
  18.  * 
  19.  * Revision 1.3  93/10/19  18:05:15  Torsten
  20.  * Localized. Defaults to builtin Danish strings if
  21.  * locale.library isn't available; thus, it still runs
  22.  * under AmigaDOS 2.04 (V37).
  23.  * 
  24.  * Revision 1.2  93/10/12  18:03:27  Torsten
  25.  * Added function prototypes.
  26.  * Can be compiled with either DICE or SAS/C 5.10.
  27.  * Tries to be smart about the screen display mode.
  28.  * Obstacles disabled on two-colour screens.  
  29.  * Knows about window border sizes.
  30.  * 
  31.  * Revision 1.1  93/10/12  00:04:41  Torsten
  32.  * This is my first version of Michael's game.
  33.  * 
  34.  */
  35.  
  36. char RCSid[] = "$Id: Orm.c,v 1.4 93/10/21 16:21:23 Torsten Rel $";
  37. char version[] = "$VER: Orm 1.4 (21.10.93)";
  38. char copyright[] = "$COPYRIGHT:*PUBLIC DOMAIN* - M. Warner & T. Poulin$";
  39.  
  40. #include <exec/types.h>
  41. #include <intuition/intuition.h>
  42. #include <libraries/locale.h>
  43. #include <clib/exec_protos.h>
  44. #include <clib/intuition_protos.h>
  45. #include <clib/graphics_protos.h>
  46. #include <clib/dos_protos.h>
  47. #include <clib/locale_protos.h>
  48. #include <stdlib.h>
  49. #include <stdio.h>
  50. #include <time.h>
  51. #include <sys/types.h>
  52. #include "orm.h"
  53.  
  54. /*
  55.  * Compiler dependencies
  56.  */
  57.  
  58. #if defined(__SASC) | defined(LATTICE) | defined(_DCC)
  59.  
  60. #ifdef _DCC
  61. void fool_DICE(void) { _waitwbmsg(); }
  62. #define main _main
  63. #define __far
  64. #define __stdargs
  65.  
  66. #else /* __SASC | LATTICE */
  67. #ifdef __SASC_510
  68. #include <pragmas/exec_pragmas.h>
  69. #include <pragmas/intuition_pragmas.h>
  70. #include <pragmas/graphics_pragmas.h>
  71. #include <pragmas/locale_pragmas.h>
  72. extern struct DosLibrary *DOSBase;
  73. #include <pragmas/dos_pragmas.h>
  74. #endif /* __SASC_510 */
  75. void main(void);
  76. void _main(char *dummy) { main(); }
  77. #endif /* __SASC | LATTICE */
  78.  
  79. #else /* something else */
  80. #define __far
  81. #define __stdargs
  82. #endif
  83.  
  84. #define XSIZE 40
  85. #define YSIZE 40
  86. #define BSIZE 3
  87. #define NFROGS 4
  88. #define PRIORITY 0
  89.  
  90. #define CLEAR 1
  91. #define SNAKE 0
  92. #define BRICK 3
  93. #define FROG  2
  94.  
  95. #define KEY_ESC   69
  96. #define KEY_Pause 64
  97. #define KEY_UP    76
  98. #define KEY_DOWN  77
  99. #define KEY_RIGHT 78
  100. #define KEY_LEFT  79
  101.  
  102. extern UWORD __stdargs RangeRand(ULONG maxValue);
  103. void exit_prog(int num);
  104. void open_window(void);
  105. void close_window(void);
  106. void notify(char *str);
  107. void set_point(int x, int y, int item);
  108. void clear_grid(void);
  109. void draw_score(void);
  110. void pause(void);
  111. void create_frog(int n);
  112. void check_frogs(void);
  113. void replace_frog(int x, int y);
  114. void setup_game(void);
  115. BOOL play_one_game(void);
  116. void play_game(void);
  117. void randomize(void);
  118. char *getcatalogstr(struct Catalog *, LONG, char *);
  119.  
  120. APTR IntuitionBase, GfxBase;
  121. struct LocaleBase *LocaleBase;
  122. struct Catalog *catalog;
  123. struct Window *win;
  124. struct RastPort *rp;
  125. LONG xstretch, ystretch;
  126. LONG border_left, border_top;
  127.  
  128. UBYTE grid[XSIZE][YSIZE];
  129. UBYTE snx[1500], sny[1500], frx[NFROGS], fry[NFROGS];
  130. int dir, length, head, tail, grow, frogtime[NFROGS];
  131. UBYTE key;
  132. BOOL has_obsta = FALSE;
  133.  
  134.  
  135. void exit_prog(int num)
  136. {
  137.   if (LocaleBase) CloseLibrary((struct Library *) LocaleBase);
  138.   if (GfxBase) CloseLibrary((struct Library *) GfxBase);
  139.   if (IntuitionBase) CloseLibrary((struct Library *) IntuitionBase);
  140.   exit(num);
  141. }
  142.  
  143.  
  144. void open_window(void)
  145. {
  146.   struct Screen *scr;
  147.   struct DrawInfo *scr_di;
  148.   char *title;
  149.  
  150.   if (!(scr = LockPubScreen(NULL)))
  151.     exit_prog(20);
  152.  
  153.   if (scr_di = GetScreenDrawInfo(scr)) {
  154.     has_obsta = scr_di->dri_Depth > 1;
  155.     FreeScreenDrawInfo(scr, scr_di);
  156.   }
  157.  
  158.   /*
  159.    * Determine stretch factors heuristically.
  160.    * Please note that this is a hack and the result
  161.    * will not be pleasing in the VGA-ExtraLores modes :-(
  162.    */
  163.   if (scr->Width <= 500)
  164.     xstretch = 1; /* Lores */
  165.   else if (scr->Width <= 800)
  166.     xstretch = 2; /* Hires */
  167.   else
  168.     xstretch = 4; /* SuperHires or A2024 */
  169.  
  170.   if (scr->Height <= 300)
  171.     ystretch = 1; /* Not interlaced */
  172.   else if (scr->Height <= 700)
  173.     ystretch = 2; /* Productivity or interlaced */
  174.   else
  175.     ystretch = 4; /* Interlaced Productivity or A2024 */
  176.  
  177.   if (has_obsta)
  178.     title = getcatalogstr(catalog, MSG_SCRTITLE1, MSG_SCRTITLE1_STR);
  179.   else
  180.     title = getcatalogstr(catalog, MSG_SCRTITLE2, MSG_SCRTITLE2_STR);
  181.  
  182.   win = OpenWindowTags(NULL,
  183.                WA_InnerWidth, XSIZE*BSIZE*xstretch+2*xstretch,
  184.                WA_InnerHeight, YSIZE*BSIZE*ystretch+2*ystretch+1,
  185.                WA_IDCMP, CLOSEWINDOW | RAWKEY,
  186.                WA_ScreenTitle, title,
  187.                WA_Flags, ACTIVATE
  188.                | WINDOWCLOSE
  189.                | WINDOWDRAG
  190.                | RMBTRAP
  191.                | WINDOWDEPTH
  192.                | SMART_REFRESH
  193.                | NOCAREREFRESH,
  194.                TAG_DONE);
  195.  
  196.   UnlockPubScreen(NULL, scr);
  197.  
  198.   if (!win)
  199.     exit_prog(20);
  200.   rp = win->RPort;
  201.   border_left = win->BorderLeft + xstretch;
  202.   border_top = win->BorderTop + ystretch;
  203. }
  204.  
  205.  
  206. void close_window(void)
  207. {
  208.   CloseWindow(win);
  209. }
  210.  
  211.  
  212. void notify(char *str)
  213. {
  214.   struct EasyStruct es;
  215.  
  216.   es.es_StructSize = sizeof(struct EasyStruct);
  217.   es.es_Flags = 0;
  218.   es.es_Title = getcatalogstr(catalog,
  219.                   MSG_EASYREQ_RESULT_TITLE,
  220.                   MSG_EASYREQ_RESULT_TITLE_STR);
  221.   es.es_TextFormat = str;
  222.   es.es_GadgetFormat = getcatalogstr(catalog,
  223.                      MSG_EASYREQ_RESULT_GAD,
  224.                      MSG_EASYREQ_RESULT_GAD_STR);
  225.   EasyRequestArgs(NULL, &es, NULL, NULL);
  226. }
  227.  
  228.  
  229. #define bleft (border_left + (x * BSIZE * xstretch))
  230. #define bwidth (border_left + (x * BSIZE * xstretch) + BSIZE * xstretch - 1)
  231. #define btop (border_top + (y * BSIZE * ystretch))
  232. #define bheight (border_top + (y * BSIZE * ystretch) + BSIZE * ystretch - 1)
  233.  
  234. void set_point(int x, int y, int item)
  235. {
  236.   grid[x][y] = item;
  237.  
  238.   SetAPen(rp, item);
  239.   RectFill(rp, bleft, btop, bwidth, bheight);
  240. }
  241.  
  242.  
  243. void clear_grid(void)
  244. {
  245.   int x, y;
  246.  
  247.   for (x = 0; x < XSIZE; x++)
  248.     for (y = 0; y < YSIZE; y++)
  249.       grid[x][y] = CLEAR;
  250.   SetAPen(rp, CLEAR);
  251.   RectFill(rp,
  252.        border_left, border_top,
  253.        border_left + XSIZE * BSIZE * xstretch,
  254.        border_top + YSIZE * BSIZE * ystretch);
  255. }
  256.  
  257.  
  258. void draw_score(void)
  259. {
  260.   static char str[20];
  261.   char *fmtstr;
  262.  
  263.   fmtstr = getcatalogstr(catalog, MSG_WINDOWTITLE, MSG_WINDOWTITLE_STR);
  264.   sprintf(str, fmtstr, length);
  265.   SetWindowTitles(win, str, (APTR) -1);
  266. }
  267.  
  268.  
  269. void pause(void)
  270. {
  271.   struct IntuiMessage *msg;
  272.  
  273.   for (;;) {
  274.     msg = (struct IntuiMessage *) WaitPort(win->UserPort);
  275.     if (msg->Class == RAWKEY && msg->Code & 0x80)
  276.       ReplyMsg(GetMsg(win->UserPort));
  277.     else
  278.       return;
  279.   }
  280. }
  281.  
  282.  
  283. void create_frog(int n)
  284. {
  285.   int x, y;
  286.  
  287.   do {
  288.     x = RangeRand(XSIZE);
  289.     y = RangeRand(YSIZE);
  290.   } while (grid[x][y] != CLEAR);
  291.   frx[n] = x;
  292.   fry[n] = y;
  293.   set_point(x, y, FROG);
  294.   frogtime[n] = 20 + RangeRand(50);
  295. }
  296.  
  297.  
  298. void check_frogs(void)
  299. {
  300.   int n, x, y;
  301.  
  302.   for (n = 0; n < NFROGS; n++) {
  303.     if (!frogtime[n]--) {
  304.       x = frx[n];
  305.       y = fry[n];
  306.       create_frog(n);
  307.       if (has_obsta)
  308.     set_point(x, y, RangeRand(10) ? CLEAR : BRICK);
  309.       else
  310.     set_point(x, y, CLEAR);
  311.     }
  312.   }
  313. }
  314.  
  315.  
  316. void replace_frog(int x, int y)
  317. {
  318.   int n;
  319.  
  320.   for (n = 0; n < NFROGS; n++) {
  321.     if (frx[n] == x && fry[n] == y)
  322.       create_frog(n);
  323.   }
  324.   set_point(x, y, CLEAR);
  325. }
  326.  
  327.  
  328. void setup_game(void)
  329. {
  330.   int i;
  331.  
  332.   clear_grid();
  333.   length = 1;
  334.   draw_score();
  335.   head = tail = 0;
  336.   snx[0] = XSIZE / 2;
  337.   sny[0] = YSIZE / 2;
  338.   set_point(snx[0], sny[0], SNAKE);
  339.   key = KEY_RIGHT;
  340.   for (i = 0; i < NFROGS; i++)
  341.     create_frog(i);
  342.   draw_score();
  343. }
  344.  
  345.  
  346. BOOL play_one_game(void)
  347. {
  348.   int item;
  349.   struct IntuiMessage *msg;
  350.   ULONG class;
  351.   USHORT code;
  352.   int x, y, nx, ny;
  353.  
  354.   for (;;) {
  355.     Delay(4L);
  356.     WaitTOF();
  357.     while (msg = (struct IntuiMessage *) GetMsg(win->UserPort)) {
  358.       class = msg->Class;
  359.       code = msg->Code;
  360.       ReplyMsg((struct Message *) msg);
  361.       switch (class) {
  362.       case CLOSEWINDOW:
  363.     return (TRUE);
  364.       case RAWKEY:
  365.     if (!(code & 0x80))
  366.       switch (code) {
  367.       case KEY_ESC:
  368.         return TRUE;
  369.       case KEY_Pause:
  370.         pause();
  371.         break;
  372.       case KEY_UP:
  373.       case KEY_DOWN:
  374.       case KEY_LEFT:
  375.       case KEY_RIGHT:
  376.         key = code;
  377.       }
  378.       }
  379.     }
  380.  
  381.     x = snx[head];
  382.     y = sny[head];
  383.     switch (key) {
  384.     case KEY_UP:
  385.       nx = x;
  386.       ny = y - 1;
  387.       break;
  388.     case KEY_DOWN:
  389.       nx = x;
  390.       ny = y + 1;
  391.       break;
  392.     case KEY_LEFT:
  393.       nx = x - 1;
  394.       ny = y;
  395.       break;
  396.     case KEY_RIGHT:
  397.       nx = x + 1;
  398.       ny = y;
  399.       break;
  400.     }
  401.     if (nx < 0 || ny < 0 || nx >= XSIZE || ny >= YSIZE)
  402.       return FALSE;
  403.     item = grid[nx][ny];
  404.     switch (item) {
  405.     case FROG:
  406.       grow += 2 + RangeRand(10);
  407.       replace_frog(nx, ny);
  408.     case CLEAR:
  409.       head = (head + 1) % 1500;
  410.       snx[head] = nx;
  411.       sny[head] = ny;
  412.       set_point(nx, ny, SNAKE);
  413.       if (grow) {
  414.     grow--;
  415.     length++;
  416.     draw_score();
  417.       } else {
  418.     set_point(snx[tail], sny[tail], CLEAR);
  419.     tail = (tail + 1) % 1500;
  420.       }
  421.       break;
  422.     case SNAKE:
  423.     case BRICK:
  424.       return (FALSE);
  425.     }
  426.     check_frogs();
  427.   }
  428. }
  429.  
  430.  
  431. void play_game(void)
  432. {
  433.   char str[80], *fmtstr;
  434.  
  435.   for (;;) {
  436.     setup_game();
  437.     WaitPort(win->UserPort);
  438.     if (play_one_game())
  439.       return;
  440.     fmtstr = getcatalogstr(catalog,
  441.                MSG_EASYREQ_RESULT,
  442.                MSG_EASYREQ_RESULT_STR);
  443.     sprintf(str, fmtstr, length);
  444.     notify(str);
  445.   }
  446. }
  447.  
  448.  
  449. void randomize(void)
  450. {
  451.   extern ULONG __far RangeSeed;
  452.   time_t t;
  453.  
  454.   time(&t);
  455.   RangeSeed = (ULONG) t;
  456. }
  457.  
  458.  
  459. char *getcatalogstr(struct Catalog *catalog, LONG strNum, char *defStr)
  460. {
  461.   if (LocaleBase)
  462.     return (char *) GetCatalogStr(catalog, strNum, defStr);
  463.   else
  464.     return defStr;
  465. }
  466.  
  467.  
  468. void main(void)
  469. {
  470.   BYTE old_pri;
  471.   struct TagItem OC_tags[2];
  472.  
  473.   OC_tags[0].ti_Tag = OC_BuiltInLanguage;
  474.   OC_tags[0].ti_Data = (ULONG) "dansk";
  475.   OC_tags[1].ti_Tag = TAG_DONE;
  476.   OC_tags[1].ti_Data = NULL;
  477.  
  478.   if (IntuitionBase = OpenLibrary("intuition.library", 37L))
  479.     if (GfxBase = OpenLibrary("graphics.library", 37L)) {
  480.       LocaleBase = (struct LocaleBase *) OpenLibrary("locale.library", 38L);
  481.       if (LocaleBase)
  482.     catalog = OpenCatalogA(NULL, "Orm.catalog", OC_tags);
  483.       randomize();
  484.       open_window();
  485.       old_pri = SetTaskPri(FindTask(0), PRIORITY);
  486.       play_game();
  487.       close_window();
  488.       SetTaskPri(FindTask(0), old_pri);
  489.       if (LocaleBase)
  490.     CloseCatalog(catalog);
  491.       }
  492.   exit_prog(0);
  493. }
  494.